#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Contains the core text manipulator and generator.
"""

from __future__ import print_function
import copy
import random

class FileReader(object):
    """
    Contains various methods for reading and manipulating vocab lists.
    """
    def __init__(self):
        """Initializes the program"""
        self._divider = self._synonym_divider = self._comment = None
        
        self.divider = ';'
        self.synonym_divider = '|'
        self.comment = '#'
        return

    def get_words_flat(self, filename):
        """
        Reads file and get words when stored in flat format.
        
        TODO: this assumes that spanish always comes first.
        This isn't the case; incorporate the metadata symbol
        ...or find a better data storage scheme.
        """
        assert(isinstance(filename, basestring))
        words_list = []
        with open(filename, 'r') as file_:
            for line in file_:
                line = self._remove_comments(line).strip()
                parts = line.split(self.divider)
                if len(parts) == 2:
                    words_list.append(self._get_pair(parts))
        return Words(words_list, ('spanish', 'english'))
    
    def get_words_xml(self, filename):
        """Reads file and gets the words when stored in XML."""
        assert(isinstance(filename, basestring))
        raise NotImplementedError('XML support not yet ready')

    def _remove_comments(self, text):
        """Removes any comments from a string"""
        return text.split(self.comment)[0]

    def _get_pair(self, parts):
        """Splits a line of text containing a tuple of two tuples which contain
        a set of synonyms"""
        left = parts[0].split(self.synonym_divider)
        right = parts[1].split(self.synonym_divider)
        left = tuple([word.strip() for word in left])
        right = tuple([word.strip() for word in right])
        return (left, right)

    def _get_divider(self):
        """Gets the divider symbol"""
        return self._divider
    def _set_divider(self, value):
        """Sets the divider symbol"""
        assert(isinstance(value, basestring))
        self._divider = value
        return
    divider = property(_get_divider, _set_divider,
                         doc="""The string dividing words""")

    def _get_synonym_divider(self):
        """Gets the synonym divider symbol"""
        return self._synonym_divider
    def _set_synonym_divider(self, value):
        """Sets the synonym divider symbol"""
        assert(isinstance(value, basestring))
        self._synonym_divider = value
        return
    synonym_divider = property(_get_synonym_divider, _set_synonym_divider,
                               doc="""The string dividing synonyms""")

    def _get_comment(self):
        """Gets the comment start symbol"""
        return self._comment
    def _set_comment(self, value):
        """Sets the comment start symbol"""
        assert(isinstance(value, basestring))
        self._comment = value
        return
    comment = property(_get_comment, _set_comment,
                       doc="""The string starting a comment""")
    

class Words(object):
    """A container class containing a set of vocab words"""
    def __init__(self, words_list, association):
        assert(len(association) == 2)
        self._list = {}
        left, right = association
        self._list[left] = list(words_list)
        self._list[right] = [(pair[1], pair[0]) for pair in words_list]
        return

    def random(self, association):
        """Returns a generator of randomly shuffled words"""
        shuffled_words = copy.copy(self._list[association])
        random.shuffle(shuffled_words)
        return ((a, b) for a, b in shuffled_words)    # generator
    
    def sequential(self, association):
        """Returns a generator of words in exact given order"""
        return ((a, b) for a, b in self._list[association])
    


